﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace sXNAke
{
    //Classe base para elementos do jogo
    abstract class GameEntity
    {
        /// <summary>
        /// A position
        /// </summary>
        public Vector2 position;
        
        /// <summary>
        /// All pixels of the image
        /// </summary>
        private Color[] colors;
        /// <summary>
        /// All pixels of the image
        /// </summary>
        public Color[] Colors
        {
            get { return colors; }
        }

        private Texture2D image;
        /// <summary>
        /// An image
        /// </summary>
        private Texture2D Image
        {
            get { return image; }
            set
            {
               image = value;
               colors = new Color[image.Width * image.Height];
               image.GetData(colors);
            }
        }

        /// <summary>
        /// if the sprite is visible
        /// </summary>
        private bool visible = true;

        protected GameWindow Window;

        private Rectangle collisionRect;
        public Rectangle CollisionRect
        {
            get
            {
                return new Rectangle((int)position.X, (int)position.Y, image.Width, image.Height);
            }
            set
            {
                collisionRect = value;
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="img">An image</param>
        public GameEntity(Texture2D img)
        {
            this.Image = img;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="img">The image of the sprite</param>
        /// <param name="position">The position of the sprite</param>
        public GameEntity(Texture2D img, Vector2 position)
        {
            this.Image = img;
            this.position = position;
        }

        /// <summary>
        /// Gets the image of this sprite
        /// </summary>
        /// <returns>The image</returns>
        public Texture2D getImage()
        {
            return this.image;
        }

        /// <summary>
        /// if this entity is visible;
        /// </summary>
        /// <returns>True if the entity is visible</returns>
        public bool isVisible()
        {
            return visible;
        }

        /// <summary>
        /// Sets the visibility of this object
        /// </summary>
        /// <param name="b"></param>
        public void setVisible(bool b)
        {
            this.visible = b;
        }

        public bool isPixelCollide(GameEntity other)
        {
            int right = Math.Min(this.CollisionRect.Right, other.CollisionRect.Right);
            int left = Math.Max(this.CollisionRect.Left, other.CollisionRect.Left);
            int bottom = Math.Min(this.CollisionRect.Bottom, other.CollisionRect.Bottom);
            int top = Math.Max(this.CollisionRect.Top, other.CollisionRect.Top);

            for (int x = left; x < right; x++)
            {
                for (int y = top; y < bottom; y++)
                {
                    Color colorA = Colors[(x - this.CollisionRect.Left) + (y - this.CollisionRect.Top) * this.CollisionRect.Width];
                    Color colorB = Colors[(x - this.CollisionRect.Left) + (y - this.CollisionRect.Top) * this.CollisionRect.Width];

                    if (colorA != null && colorB != null)
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Update this entity
        /// </summary>
        /// <param name="gameTime">The time of the game</param>
        public abstract void update(GameTime gameTime);

        /// <summary>
        /// draws this entity
        /// </summary>
        /// <param name="spriteBatch">A spriteBatch</param>
        public abstract void draw(SpriteBatch spriteBatch);
    }
}
